﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BuildPlannerLib.Buildings;
using BuildPlannerLib.Enums;
using BuildPlannerLib.PlayerActions;
using BuildPlannerLib.SimEvents;
using BuildPlannerLib.Terran.Buildings;
using BuildPlannerLib.Terran.Enums;

namespace BuildPlannerLib.Terran.PlayerActions
{
    // Derived class from Action for producing Terran units
    public class ProduceTerranUnit : PlayerAction
    {
        // Field for the unit being made
        public TerranUnit Unit;

        // Field for the production facility
        public IndividualAddonBuilding Building;

        // Constructor with parameters for build and unit
        public ProduceTerranUnit(Build build, TerranUnit unit)
        {
            Build = build;
            Unit = unit;
            MineralCost = Unit.MineralCost;
            GasCost = Unit.GasCost;
            SupplyCost = Unit.SupplyCost;
            TimeDuration = Unit.TimeDuration;
            Description = "Produce " + Unit.Name;
            LongDescription = "Producing a new " + Unit.Name + " from " + Unit.ProducedFrom + ".";
        }

        // Evaluates whether the player is Terran, whether there is mineral income or enough minerals, whether there is gas income or enough gas,
        // whether there will be supply available, whether the requirement building is started, and whether the production building is started
        public override bool RequirementsFilled()
        {
            AddonBuilding building = Build.Player.GetBuilding(Unit.ProducedFrom) as AddonBuilding;
            Building requirementBuilding = null;
            if (Unit.Requirement != null)
                requirementBuilding = Build.Player.GetBuilding(Unit.Requirement);
            Error = null;

            if (building == null)
            {
                Error = "This unit can only be built by Terran players.";
                return false;
            }

            bool availableBuilding = false;
            if (Unit.TechLab)
            {
                availableBuilding = building.IndividualBuildings.Exists(delegate(IndividualBuilding i)
                {
                    IndividualAddonBuilding a = i as IndividualAddonBuilding;
                    return a.AddonType == AddonType.TechLab;
                });
            }
            else
                availableBuilding = (building.Started > 0);
            if (!availableBuilding)
            {
                Error = "There are no production buildings that can produce this unit.";
                return false;
            }

            if (requirementBuilding != null && requirementBuilding.Started == 0)
            {
                Error = "The required building \"" + Unit.Requirement + "\" has not been built.";
                return false;
            }

            return base.RequirementsFilled();
        }

        // Evaluates if there are enough minerals, enough gas, enough supply, requirement building is finished, and production facility is not in-use
        public override bool StartCheck()
        {
            AddonBuilding building = Build.Player.GetBuilding(Unit.ProducedFrom) as AddonBuilding;
            Building requirementBuilding = null;
            if (Unit.Requirement != null)
                requirementBuilding = Build.Player.GetBuilding(Unit.Requirement);

            if (requirementBuilding != null && requirementBuilding.GetCount() == 0)
                return false;

            bool buildingAvailable = false;
            if (Unit.TechLab)
            {
                buildingAvailable = building.IndividualBuildings.Exists(delegate(IndividualBuilding i)
                {
                    IndividualAddonBuilding a = i as IndividualAddonBuilding;
                    return a.AddonType == AddonType.TechLab && !i.InUse;
                });
            }
            else
            {
                buildingAvailable = building.IndividualBuildings.Exists(delegate(IndividualBuilding i)
                {
                    IndividualAddonBuilding a = i as IndividualAddonBuilding;
                    return !i.InUse || (a.AddonType == AddonType.Reactor && !a.AddonInUse);
                });
            }
            if (!buildingAvailable)
                return false;

            return base.StartCheck();
        }

        // Spends the minerals, spends the gas, uses the supply, puts the production building in-use and adds the event to finish the action
        public override void StartAction()
        {
            AddonBuilding building = Build.Player.GetBuilding(Unit.ProducedFrom) as AddonBuilding;

            base.StartAction();

            if (Unit.TechLab)
            {
                Building = building.IndividualBuildings.Find(delegate(IndividualBuilding i)
                {
                    IndividualAddonBuilding a = i as IndividualAddonBuilding;
                    return a.AddonType == AddonType.TechLab && !i.InUse;
                }) as IndividualAddonBuilding;
            }
            else
            {
                Building = building.IndividualBuildings.Find(delegate(IndividualBuilding i)
                {
                    IndividualAddonBuilding a = i as IndividualAddonBuilding;
                    return !i.InUse || (a.AddonType == AddonType.Reactor && !a.AddonInUse);
                }) as IndividualAddonBuilding;
            }

            Building.StartProduction();
        }

        // Sets the production facility from being in-use and adds the unit
        public override void FinishAction()
        {
            base.FinishAction();

            Unit.Count++;
            Building.FinishProduction();
        }
    }
}
